{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To use MongoDB as a toolbox, you will need to complete the following steps:\n",
    "\n",
    "1. Register for a MongoDB Account:\n",
    "   - Go to the MongoDB website (https://www.mongodb.com/cloud/atlas/register).\n",
    "   - Click on the \"Try Free\" or \"Get Started Free\" button.\n",
    "   - Fill out the registration form with your details and create an account.\n",
    "\n",
    "2. Create a [MongoDB Cluster](https://www.mongodb.com/docs/atlas/tutorial/deploy-free-tier-cluster/#procedure)\n",
    "\n",
    "3. Set Up [Database Access](https://www.mongodb.com/docs/atlas/security-add-mongodb-users/#add-database-users):\n",
    "   - In the left sidebar, click on \"Database Access\" under \"Security\".\n",
    "   - Click \"Add New Database User\".\n",
    "   - Create a username and a strong password. Save these credentials securely.\n",
    "   - Set the appropriate permissions for the user (e.g., \"Read and write to any database\").\n",
    "\n",
    "4. Configure Network Access:\n",
    "   - In the left sidebar, click on \"Network Access\" under \"Security\".\n",
    "   - Click \"Add IP Address\".\n",
    "   - To allow access from anywhere (not recommended for production), enter 0.0.0.0/0.\n",
    "   - For better security, whitelist only the specific IP addresses that need access.\n",
    "\n",
    "5. Obtain the [MongoDB URI](https://www.mongodb.com/docs/manual/reference/connection-string/#find-your-mongodb-atlas-connection-string):\n",
    "\n",
    "Now that you have your MongoDB URI, you can use it to connect to your cluster in the `memorizz` library."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pip install -e ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from memorizz import MongoDBToolsConfig, MongoDBTools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import getpass\n",
    "\n",
    "# Set up environment variables for API keys and MongoDB URI\n",
    "# This key is required for using OpenAI's services, such as generating embeddings\n",
    "OPENAI_API_KEY = getpass.getpass(\"OpenAI API Key: \")\n",
    "os.environ[\"OPENAI_API_KEY\"] = OPENAI_API_KEY\n",
    "\n",
    "# This URI is needed to connect to the MongoDB database\n",
    "MONGO_URI = getpass.getpass(\"Enter MongoDB URI: \")\n",
    "os.environ[\"MONGO_URI\"] = MONGO_URI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:Vector search index 'vector_index' created.\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:MongoDBTools initialized successfully.\n"
     ]
    }
   ],
   "source": [
    "# 1. Initialize the MongoDB configuration and create a MongoDB tools instance\n",
    "from memorizz.embeddings.openai import get_embedding\n",
    "\n",
    "config = MongoDBToolsConfig(\n",
    "    mongo_uri=MONGO_URI,  # MongoDB connection string\n",
    "    db_name=\"function_calling_new\",  # Name of the database to use\n",
    "    collection_name=\"tools\",  # Name of the collection to store tools\n",
    "    vector_search_candidates=150,  # Number of candidates to consider in vector search\n",
    "    vector_index_name=\"vector_index\",  # Name of the vector index in MongoDB\n",
    "    get_embedding=get_embedding\n",
    ")\n",
    "\n",
    "# 2. Create an instance of MongoDBTools with the configured settings\n",
    "mongodb_tools = MongoDBTools(config)\n",
    "\n",
    "# 3. Create a decorator function for registering tools\n",
    "mongodb_toolbox = mongodb_tools.mongodb_toolbox"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:Successfully registered tool: shout\n",
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:Successfully registered tool: get_weather\n",
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:Successfully registered tool: get_stock_price\n",
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:Successfully registered tool: get_current_time\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "from datetime import datetime\n",
    "\n",
    "# 4. Define and register tool functions using the mongodb_toolbox decorator\n",
    "# These functions will be stored in the MongoDB database and can be retrieved for function calling\n",
    "@mongodb_toolbox()\n",
    "def shout(statement: str) -> str:\n",
    "  \"\"\"\n",
    "  Convert a statement to uppercase letters to emulate shouting. Use this when a user wants to emphasize something strongly or when they explicitly ask to 'shout' something..\n",
    "\n",
    "  \"\"\"\n",
    "  return statement.upper()\n",
    "\n",
    "@mongodb_toolbox()\n",
    "def get_weather(location: str, unit: str = \"celsius\") -> str:\n",
    "    \"\"\"\n",
    "    Get the current weather for a specified location.\n",
    "    Use this when a user asks about the weather in a specific place.\n",
    "\n",
    "    :param location: The name of the city or location to get weather for.\n",
    "    :param unit: The temperature unit, either 'celsius' or 'fahrenheit'. Defaults to 'celsius'.\n",
    "    :return: A string describing the current weather.\n",
    "    \"\"\"\n",
    "    conditions = [\"sunny\", \"cloudy\", \"rainy\", \"snowy\"]\n",
    "    temperature = random.randint(-10, 35)\n",
    "\n",
    "    if unit.lower() == \"fahrenheit\":\n",
    "        temperature = (temperature * 9/5) + 32\n",
    "\n",
    "    condition = random.choice(conditions)\n",
    "    return f\"The weather in {location} is currently {condition} with a temperature of {temperature}°{'C' if unit.lower() == 'celsius' else 'F'}.\"\n",
    "\n",
    "@mongodb_toolbox()\n",
    "def get_stock_price(symbol: str) -> str:\n",
    "    \"\"\"\n",
    "    Get the current stock price for a given stock symbol.\n",
    "    Use this when a user asks about the current price of a specific stock.\n",
    "\n",
    "    :param symbol: The stock symbol to look up (e.g., 'AAPL' for Apple Inc.).\n",
    "    :return: A string with the current stock price.\n",
    "    \"\"\"\n",
    "    price = round(random.uniform(10, 1000), 2)\n",
    "    return f\"The current stock price of {symbol} is ${price}.\"\n",
    "\n",
    "@mongodb_toolbox()\n",
    "def get_current_time(timezone: str = \"UTC\") -> str:\n",
    "    \"\"\"\n",
    "    Get the current time for a specified timezone.\n",
    "    Use this when a user asks about the current time in a specific timezone.\n",
    "\n",
    "    :param timezone: The timezone to get the current time for. Defaults to 'UTC'.\n",
    "    :return: A string with the current time in the specified timezone.\n",
    "    \"\"\"\n",
    "    current_time = datetime.utcnow().strftime(\"%H:%M:%S\")\n",
    "    return f\"The current time in {timezone} is {current_time}.\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 5. Define the user query\n",
    "# This query will be used to search for relevant tools in the MongoDB database\n",
    "user_query = \"Hi, can you shout the statement: We are there\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
      "INFO:memorizz.database.mongodb.mongodb_tools:Successfully populated 2 tools\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'_id': ObjectId('677b8d78ba939fbcff8999ca'), 'name': 'shout', 'description': \"Convert a statement to uppercase letters to emulate shouting. Use this when a user wants to emphasize something strongly or when they explicitly ask to 'shout' something..\", 'parameters': {'type': 'object', 'properties': {'statement': {'type': 'string', 'description': 'Parameter statement'}}, 'required': ['statement'], 'additionalProperties': False}}\n",
      "{'_id': ObjectId('677b8d7aba939fbcff8999cc'), 'name': 'get_stock_price', 'description': \"Get the current stock price for a given stock symbol.\\nUse this when a user asks about the current price of a specific stock.\\n\\n:param symbol: The stock symbol to look up (e.g., 'AAPL' for Apple Inc.).\\n:return: A string with the current stock price.\", 'parameters': {'type': 'object', 'properties': {'symbol': {'type': 'string', 'description': 'Parameter symbol'}}, 'required': ['symbol'], 'additionalProperties': False}}\n"
     ]
    }
   ],
   "source": [
    "# 6. Populate tools based on the user query\n",
    "tools = mongodb_tools.populate_tools(\n",
    "    user_query,  # The query string to search for relevant tools\n",
    "    num_tools=2  # The maximum number of tools to return from the search\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'function': {'description': 'Convert a statement to uppercase letters to '\n",
      "                              'emulate shouting. Use this when a user wants to '\n",
      "                              'emphasize something strongly or when they '\n",
      "                              \"explicitly ask to 'shout' something..\",\n",
      "               'name': 'shout',\n",
      "               'parameters': {'additionalProperties': False,\n",
      "                              'properties': {'statement': {'description': 'Parameter '\n",
      "                                                                          'statement',\n",
      "                                                           'type': 'string'}},\n",
      "                              'required': ['statement'],\n",
      "                              'type': 'object'}},\n",
      "  'type': 'function'},\n",
      " {'function': {'description': 'Get the current stock price for a given stock '\n",
      "                              'symbol.\\n'\n",
      "                              'Use this when a user asks about the current '\n",
      "                              'price of a specific stock.\\n'\n",
      "                              '\\n'\n",
      "                              ':param symbol: The stock symbol to look up '\n",
      "                              \"(e.g., 'AAPL' for Apple Inc.).\\n\"\n",
      "                              ':return: A string with the current stock price.',\n",
      "               'name': 'get_stock_price',\n",
      "               'parameters': {'additionalProperties': False,\n",
      "                              'properties': {'symbol': {'description': 'Parameter '\n",
      "                                                                       'symbol',\n",
      "                                                        'type': 'string'}},\n",
      "                              'required': ['symbol'],\n",
      "                              'type': 'object'}},\n",
      "  'type': 'function'}]\n"
     ]
    }
   ],
   "source": [
    "import pprint\n",
    "\n",
    "pprint.pprint(tools)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
